package com.admin.system.modules.system.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.admin.common.exception.BadRequestException;
import com.admin.core.dto.DeptQueryDTO;
import com.admin.core.entity.SysDept;
import com.admin.core.entity.SysRoleDept;
import com.admin.core.entity.SysUser;
import com.admin.core.mapper.DeptMapper;
import com.admin.core.mapper.RoleDeptMapper;
import com.admin.core.mapper.UserMapper;
import com.admin.system.modules.system.service.DeptService;
import com.admin.system.util.DataScopeWrapperUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * @author sq-lan
 */
@Service
@RequiredArgsConstructor
public class DeptServiceImpl extends ServiceImpl<DeptMapper, SysDept> implements DeptService {

    private final DeptMapper deptMapper;
    private final UserMapper userMapper;
    private final RoleDeptMapper roleDeptMapper;

    @Override
    public List<SysDept> list(DeptQueryDTO dto) {
        // todo 会把其它同级的子级显示
        LambdaQueryWrapper<SysDept> wrapper = Wrappers.lambdaQuery();
        if (org.springframework.util.StringUtils.hasText(dto.getName())) {
            wrapper.like(SysDept::getName, dto.getName());
        }
        if (dto.getEnabled() != null) {
            wrapper.eq(SysDept::getEnabled, dto.getEnabled());
        }
        if (dto.getPid() != null) {
            wrapper.eq(SysDept::getPid, dto.getPid());
        }
        if (dto.getCreateTime() != null && !dto.getCreateTime().isEmpty()) {
            wrapper.between(SysDept::getCreateTime, dto.getCreateTime().get(0), dto.getCreateTime().get(1));
        }
        DataScopeWrapperUtil.dataScopeForDept(wrapper);
        wrapper.select(SysDept::getId, SysDept::getPid, SysDept::getName, SysDept::getEnabled, SysDept::getDeptSort);
        return this.list(wrapper);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void modify(SysDept entity) {
        // todo 上级不能是自己 或 之前的子级
        // Integer oldPid = getById(entity.getId()).getPid();
        // Integer newPid = entity.getPid();
        if (entity.getPid() != null && entity.getId().equals(entity.getPid())) {
            throw new BadRequestException("上级不能为自己");
        }
        this.updateById(entity);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void remove(Set<Integer> ids) {
        Set<Integer> set = new HashSet<>();
        for (Integer id : ids) {
            set.add(id);
            List<SysDept> childrenList = this.list(Wrappers.<SysDept>lambdaQuery().select(SysDept::getId).eq(SysDept::getPid, id).eq(SysDept::getEnabled, true));
            if (CollectionUtil.isNotEmpty(childrenList)) {
                this.recursionChildId(childrenList, set);
            }
        }

        if (userMapper.selectCount(Wrappers.<SysUser>lambdaQuery().in(SysUser::getDeptId, set)) > 0) {
            throw new BadRequestException("所选部门存在用户关联，请先解除");
        }
        if (roleDeptMapper.selectCount(Wrappers.<SysRoleDept>lambdaQuery().in(SysRoleDept::getDeptId, set)) > 0) {
            throw new BadRequestException("所选部门存在角色关联，请先解除");
        }

        for (Integer id : set) {
            deptMapper.deleteById(id);
        }
    }

    @Override
    public void recursionChildId(List<SysDept> list, Set<Integer> set) {
        for (SysDept dept : list) {
            set.add(dept.getId());
            List<SysDept> subList = this.list(Wrappers.<SysDept>lambdaQuery().select(SysDept::getId).eq(SysDept::getPid, dept.getId()).eq(SysDept::getEnabled, true));
            if (subList != null && !subList.isEmpty()) {
                recursionChildId(subList, set);
            }
        }
    }

}
